package engine

import (
	"net/http"
	"time"

	"github.com/ChuranNeko/gginx/pkg/security"
)

// Config 代理引擎配置
type Config struct {
	Balancer *BalancerConfig `yaml:"balancer"`
	WAF      *WAFConfig      `yaml:"waf"`
	HTTPS    *HTTPSConfig    `yaml:"https"`
}

type HTTPSConfig struct {
	Enabled     bool     `yaml:"enabled"`
	Domains     []string `yaml:"domains"`
	CacheDir    string   `yaml:"cache_dir"`
	RenewBefore string   `yaml:"renew_before"` // 如"720h"表示30天
}

type BalancerConfig struct {
	Strategy string   `yaml:"strategy"`
	Backends []string `yaml:"backends"`
}

type WAFConfig struct {
	Rules []security.WAFRule `yaml:"rules"`
}

type ProxyEngine struct {
	balancer      *LoadBalancer
	waf           *security.WAF
	healthChecker *HealthChecker
	certManager   *security.CertManager
	stopChan      chan struct{}
}

func NewProxyEngine(cfg *Config) (*ProxyEngine, error) {
	lb, err := NewLoadBalancer(cfg.Balancer)
	if err != nil {
		return nil, err
	}

	waf := security.NewWAF()
	if cfg.WAF != nil {
		for _, rule := range cfg.WAF.Rules {
			if err := waf.AddRule(&rule); err != nil {
				return nil, err
			}
		}
	}

	engine := &ProxyEngine{
		balancer: lb,
		waf:      waf,
		stopChan: make(chan struct{}),
	}

	// 初始化HTTPS证书管理
	if cfg.HTTPS != nil && cfg.HTTPS.Enabled {
		renewBefore := 30 * 24 * time.Hour // 默认30天
		if cfg.HTTPS.RenewBefore != "" {
			if d, err := time.ParseDuration(cfg.HTTPS.RenewBefore); err == nil {
				renewBefore = d
			}
		}

		certManager := security.NewCertManager(cfg.HTTPS.Domains, cfg.HTTPS.CacheDir)
		certManager.RenewBefore = renewBefore
		go certManager.StartAutoRenew()
		engine.certManager = certManager
	}

	return engine, nil
}

func (p *ProxyEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if !p.waf.IsAllowed(r) {
		http.Error(w, "Forbidden", http.StatusForbidden)
		return
	}

	backend := p.balancer.Next()
	if backend == nil {
		http.Error(w, "Service Unavailable", http.StatusServiceUnavailable)
		return
	}

	backend.ServeHTTP(w, r)
}

// StartHealthCheck 启动健康检查
func (p *ProxyEngine) StartHealthCheck(interval, timeout time.Duration) {
	p.healthChecker = NewHealthChecker(p.balancer.backends, interval, timeout, "/health")
	p.healthChecker.Start()
}

// StopHealthCheck 停止健康检查
func (p *ProxyEngine) StopHealthCheck() {
	if p.healthChecker != nil {
		p.healthChecker.Stop()
	}
}

// Shutdown 优雅关闭代理引擎
func (p *ProxyEngine) Shutdown() {
	p.StopHealthCheck()
	close(p.stopChan)

	// 关闭负载均衡器连接
	if p.balancer != nil {
		p.balancer.Close()
	}
}
